package com.multi.thread;

//import org.springframework.web.context.request.RequestAttributes; // 这个是用于spring上下文用的
//import org.springframework.web.context.request.RequestContextHolder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class TestExecutorService {
    public static void main(String[] args) {
        System.out.println(new TestExecutorService().test());
    }

    public List<String> test() {
        // 创建线程池（推荐使用ThreadPoolExecutor而不是Executors）
        ExecutorService executorService = new ThreadPoolExecutor(
                2, 2, 60L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                new ThreadPoolExecutor.CallerRunsPolicy());

        List<Future<String>> futureTaskList = new ArrayList<>();

        List<Integer> segmentsList = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 父线程中设置上下文（如拦截器或Controller）
        YourThreadLocalContext.set("userId", "user123");
        YourThreadLocalContext.set("tenantId", "tenantA");

        try {
            // 提交所有任务
            segmentsList.forEach(item -> {
                /*// 无上下文传递的
                Callable<String> task = createSegmentTask(item);
                futureTaskList.add(executorService.submit(task));*/

                // 有上下文传递的
                // 包装任务以传递上下文
                Callable<String> originalTask = createSegmentTask(item);
                Callable<String> wrappedTask = new ContextAwareCallable<>(originalTask);
                futureTaskList.add(executorService.submit(wrappedTask));
            });

            // 收集结果
            List<String> strings = processFutures(futureTaskList);
            System.out.println("All tasks completed.");
            return strings;
        } finally {

            // 确保线程池关闭
            shutdownExecutor(executorService);
        }

    }

    // 封装任务创建逻辑
    private Callable<String> createSegmentTask(Integer item) {
        return () -> {
            long id = Thread.currentThread().getId();

            if (item % 3 == 0) {
                TimeUnit.SECONDS.sleep(10);
            }
            String userId = (String) YourThreadLocalContext.get("userId"); // 输出 "user123"
            System.out.println(">>>>>>>> Thread ID: " + id + ", Item: " + item + ", User ID: " + userId);
            return item + "++++++" + id;
        };
    }

    // 处理Future结果
    private List<String> processFutures(List<Future<String>> futures) {
        List<String> results = new ArrayList<>();

        for (Future<String> future : futures) {
            try {
                // 设置合理的超时时间
//                results.add(future.get(3, TimeUnit.SECONDS));
                results.add(future.get());
            }
            /*catch (TimeoutException e) {
                future.cancel(true);
                System.err.println("Task timeout: " + e);
            } */
            catch (ExecutionException e) {
                System.err.println("Task execution failed" + e.getCause());

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("Task interrupted" + e);
            }
        }

        return results;
    }

    // 安全关闭线程池
    private void shutdownExecutor(ExecutorService executor) {
        System.out.println("Shutting down executor...");
        executor.shutdown();
        try {
            // 等待线程池终止，设置超时时间
            if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
                // 线程池未终止，强制关闭
                executor.shutdownNow();
                System.out.println("Executor did not terminate in the specified time, forcing shutdown.");
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    public class ContextAwareCallable<T> implements Callable<T> {
        private final Callable<T> delegate;
//        private final RequestAttributes requestAttributes;
        private final Map<String, Object> customContext;

        public ContextAwareCallable(Callable<T> delegate) {
            this.delegate = delegate;
//            this.requestAttributes = RequestContextHolder.getRequestAttributes(); // Spring 上下文
            this.customContext = YourThreadLocalContext.get(); // 自定义 ThreadLocal
        }

        @Override
        public T call() throws Exception {
            try {
                // 绑定上下文到子线程
//                RequestContextHolder.setRequestAttributes(requestAttributes);
                YourThreadLocalContext.set(customContext);
                return delegate.call();
            } finally {
                // 清理子线程上下文
//                RequestContextHolder.resetRequestAttributes();
                YourThreadLocalContext.remove();
            }
        }
    }

    public class YourThreadLocalContext {
        // 1. 定义 ThreadLocal
        private static final ThreadLocal<Map<String, Object>> contextHolder = ThreadLocal.withInitial(HashMap::new);

        // 2. 存储上下文值
        public static void set(String key, Object value) {
            contextHolder.get().put(key, value);
        }

        // 3. 获取上下文值
        public static Object get(String key) {
            return contextHolder.get().get(key);
        }

        // 4. 获取全部上下文（用于跨线程传递）
        public static Map<String, Object> get() {
            return new HashMap<>(contextHolder.get());
        }

        // 5. 设置全部上下文（用于跨线程恢复）
        public static void set(Map<String, Object> context) {
            contextHolder.get().clear();
            contextHolder.get().putAll(context);
        }

        // 6. 清除上下文（防止内存泄漏）
        public static void remove() {
            contextHolder.remove();
        }
    }


}
